package com.wxit.algorithm.array;

import java.util.Arrays;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.stream.IntStream;

/**
 * 动态数组
 */

public class DynamicArray implements Iterable<Integer> {

    private int size = 0;
    private int total = 8;
    private int[] array = {};


    /**
     * 在数组最后添加元素
     */
    public void addLast(int element) {
        array[size] = element;
        size++;
    }

    /**
     * 根据索引位置获取元素
     * @param index  [0, size) 左闭右开
     * @return 对应索引值
     */
    public int get(int index) {
        return array[index];
    }

    /**
     * 插入元素
     * @param index 索引位置
     * @param element 待插入的元素
     */
    public void add(int index, int element) {
        //容量检查
        check();

        if (index >= 0 && index < size) {
            //参数2：开始拷贝的位置 参数3:目标数组 参数4：目标数组的起始位置 参数5：要拷贝的元素个数
            //[ 1, 2, 3, 4, 5, 6, 0, 0 ]
            //[ 1, 2, 3, 3, 4, 5, 6, 0 ]
            //[ 1, 2, 9, 3, 4, 5, 6, 0 ]
            System.arraycopy(array, index, array, index + 1, size - index);
        }
        array[index] = element;
        size++;
    }

    /**
     *容量检查
     */
    private void check() {
        if (size == total) {
            total += total >> 1;
            int[] newArray = new int[total];
            System.arraycopy(array, 0, newArray, 0, size);
            array = newArray;
        } else if (size == 0) {
            array = new int[total];
        }
    }

    /**
     * 遍历元素
     */
    public void foreach(Consumer<Integer> consumer) {
        for (int i = 0; i < size; i++) {
            consumer.accept(array[i]);
        }
    }

    /**
     * 迭代器遍历
     * @return
     */
    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            int i = 0;
            //有没有下一个元素
            @Override
            public boolean hasNext() {
                return i < size;
            }
            //返回当前元素，并移动到下一个元素
            @Override
            public Integer next() {
                return array[i++];
            }
        };
    }

    /**
     * 流的方式遍历
     * @return
     */
    public IntStream stream() {
        return IntStream.of(Arrays.copyOfRange(array, 0, size));
    }

    public int remove(int index) {
        int remove = array[index];
        System.arraycopy(array, index + 1, array, index, size - index - 1);
        size--;
        return remove;
    }
}
